/**********************************
    创建时间:2020年6月1日16:27:18
    更新时间:2020年7月24日21:21:15
    创建人:  王尼玛1

    说明: 使用tone函数会和其他定时器起冲突，暂时不用tone函数

 **********************************/
#include <Arduino.h>
#include <SPI.h>
#include <Wire.h>
#include <EEPROM.h>
#include <MsTimer2.h>
#include <SoftwareSerial.h>
#include <Adafruit_NeoPixel.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "Motor.h"
#include "RGB.h"
#include "BY8001.h"
#include "OLED.h"
#include "music.h"

#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif

#define PIN     12 // 连接RGB灯带的引脚
#define NUMPIXELS 14 // RGB灯数
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET     4

Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
SoftwareSerial mySerial(10, 11); // RX, TX
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);


int addr = 0;
int Speed = 0;
long count, count1;
unsigned char n;
unsigned char sec, min, hou, lastsec, lastmin, lasthou;
unsigned int rgb;


bool flag = false; //写入EEPROM标志位
bool flag2 = false; //1秒标志位
/********************************
   函数功能:定时器中断函数
   传入参数：无
   返回值: 无
 ********************************/
void flash()
{
  sec++;
  flag2 = true;
  count1 = count;
  count = 0;
}
/********************************
   函数功能:初始化RGB
   传入参数：无
   返回值: 无
 ********************************/
void RGB_init()
{
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
#endif

  pixels.begin();
}


/********************************
   函数功能:初始化OLED
   传入参数：无
   返回值: 无
 ********************************/
void oled_init()
{
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for (;;); // Don't proceed, loop forever
  }
  display.display();
  delay(1000);
  display.clearDisplay();
  for (int i = 0; i < 100; i++)
  {
    display.clearDisplay();
    display.setTextSize(1);             // Normal 1:1 pixel scale
    display.setTextColor(SSD1306_WHITE);        // Draw white text
    display.setCursor(0, 0);            // Start at top-left corner
    display.println(F("Starting...."));
    display.setCursor(100, 0);            // Start at top-left corner
    display.println(F("%"));
    display.setCursor(80, 0);
    display.println(i);

    display.display();
    delay(5);
  }
}

/********************************
   函数功能：读取上次保存的数据
   传入参数：无
   返回值: 无
 ********************************/
void readlastData()
{
  lastsec = EEPROM.read(0);
  lastmin = EEPROM.read(1);
  lasthou = EEPROM.read(2);
}


/********************************
   函数功能：外部中断触发事件
   传入参数：无
   返回值: 无
 ********************************/
void blink()
{
  count++;
}

/********************************
   函数功能：控制小车和音乐
   传入参数：串口指令
   返回值: 无
 ********************************/
void SerialCmd(char cmd)
{
  switch (cmd)
  {
    case '0': stopcar(); break;
    case '1': go(); break;
    case '2': goback(); break;
    case '3': trunleft(); break;
    case '4': trunright(); break;
    case 'T': sendcmdToBY8001(1);break;
    case 'Z': sendcmdToBY8001(2); break;
    case 'R': sendcmdToBY8001(3);break;
    case 'L': sendcmdToBY8001(4); break;
    case 'u': sendcmdToBY8001(5); break;
    case 'd': sendcmdToBY8001(6); break;
    case 'A': rgb+=1; break;
    default: break;
  }

}

/********************************
   函数功能：需要初始化的都放入这里
   传入参数：无
   返回值: 无
 ********************************/
void setup() {
  Init_pin();
  
  RGB_init();
  oled_init();
  readlastData();
  MsTimer2::set(1000, flash); // 1s period
  MsTimer2::start();
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);

  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
  pinMode(2, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(2), blink, FALLING);
  Serial.begin(9600);
  mySerial.begin(9600);
//  beep_play();
//  player_music(1);
 randomSeed(analogRead(A3));
 
}
/********************************
   函数功能：主函数入口
   传入参数：无
   返回值: 无
 ********************************/
void loop()
{
  
  
  while(Serial.available() > 0)
  {
    n  = Serial.read();
     if(n=='Q')
    {
         Speed = Serial.parseInt(); 
     }
     else
      SerialCmd(n);
  }
 
 
  oled_displayTimeandSpeed();
  if (flag)
  {
    flag = false;
    // EEPROM.write(0, sec);
    // EEPROM.write(1, min);
    // EEPROM.write(2, hou);
  }
  if (flag2)
  {
    flag2 = false;
    detachInterrupt(digitalPinToInterrupt(2));
    count1 = count1 / 20 * 60;
    Serial.print("*D");
    Serial.print(count1);
    Serial.print('*');
    attachInterrupt(digitalPinToInterrupt(2), blink, FALLING);
  }
 
 switch(rgb)
 {
   case 0: mode4('B');break;
   case 1: mode2();break;
   case 2: mode3();break;
   case 3: mode6();break;
   case 4: mode5();break;
   case 5: mode1();break;
   case 6: mode7();break;
   default:break;
 }
  if(rgb>7) rgb = 0;
}
